package com.miaopasi.securitydemo.config.security;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 自定查询UserDetails
 *
 * @author lixin
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Console.log("根据用户名查询UserDetails，{}", username);
        Optional<UserDetails> first = userDetailsList().stream().filter(userDetails -> Objects.equals(userDetails.getUsername(), username)).findFirst();
        if (first.isPresent()) {
            return first.get();
        }
        throw new BadCredentialsException("[" + username + "]用户不存在");
    }

    /**
     * 模拟从数据库查询出来的用户信息列表
     */
    private List<UserDetails> userDetailsList() {
        List<UserDetails> userDetails = new ArrayList<>(10);
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        SysUser user;
        for (int i = 0; i < 10; i++) {
            user = new SysUser();
            user.setId(Convert.toLong(i));
            user.setGmtCreate(DateTime.now());
            user.setOperator("管理员");
            user.setIsDelete(false);
            user.setSort(BigDecimal.valueOf(0));
            user.setStatus(0);
            user.setRemarks("测试用户" + i);
            user.setUsername("user" + i);
            user.setPassword(passwordEncoder.encode("pwd_" + i));
            userDetails.add(user);
        }

        // 输出userDetails
        userDetails.forEach(Console::log);

        return userDetails;
    }
}
